package com.dcy.znoa.common.util.wj.louxing6.louxing;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * wj 楼型比例算法 2-6个出参（整数），若干入参:业态去化速度/业态层数/业态面积 的数量与出参数量相等
 * v1.0 目前只有自然数最优解
 * Created by pengyu on 2018/07/01.
 * <p>
 * 已知输入条件：
 * 1. 业态名称[业态A，业态B，业态C，业态D] ——name[a,b,c,d]
 * 2. 业态去化速度[速度A，速度B，速度C，速度D]——speed[a,b,c,d]
 * 3. 业态层数[层数A，层数B，层数C，层数D]——floor[a,b,c,d]
 * 4. 业态面积[面积A，面积B，面积C，面积D]——area[a,b,c,d]
 * 5. 容积率——PR
 * 6. 用地面积——LA
 * 7. 建筑密度——BD
 * 8. 月去化速度——@1
 * <p>
 * 输出结果：（该结果会有多个，输出所有的结果）
 * 业态栋数[栋数A，栋数B，栋数C，栋数D]——x[1,2,3,4]
 * <p>
 * 计算约束条件：
 * 1. speed[a]*x[1]+speed[b]*x[2]+speed[c]*x[3]+speed[d]*x[4] ≥ @1；
 * 2. x[1]*area[a]*floor[a]+x[2]*area[b]*floor[b]+x[3]*area[c]*floor[c]+x[4]*area[d]*floor[d] ≤PR*LA；
 * 3. x[1]*area[a]+x[2]*area[b]+x[3]*area[c]+x[4]*area[4] ≤BD*LA
 * <p>
 * 数据例子：
 * 1. name[高层,T4洋房,T2洋房,别墅]
 * 2. speed[35,15,6,1]
 * 3. floor[33,18,18,4]
 * 4. area[420,400,270,150]
 * 5. PR=300%    //5%
 * 6. LA=33250     //9706
 * 7. BD=29%
 * 8. @1=208
 * <p>
 * 求满足条件的所有 x[1,2,3,4] 组合；
 */
public class HouseWjSix180726 {

    //area 对应的参数不能为0
    public static void main(String[] args) {
//        BigDecimal pr = new BigDecimal(3);
//        BigDecimal bd = new BigDecimal(0.29);
//        WjSixInput wj2Input = new WjSixInput(4,
//                35, 15, 6, 1, null, null,
//                33, 18, 18, 4, null, null,
//                420, 400, 270, 150, null, null,
//                pr, 33250, bd, 208);
//
//        getOut(wj2Input);

        BigDecimal pr = new BigDecimal(2.36);
        BigDecimal bd = new BigDecimal(0.245);
        /*BigDecimal pr = new BigDecimal(3);
        BigDecimal bd = new BigDecimal(0.29);
        /*WjSixInput wj2Input = new WjSixInput(4,
                35, 15, 6, 1, null, null,
                33, 18, 18, 4, null, null,
                420, 400, 270, 150, null, null,
                pr, 33250, bd, 208);*/


        WjSixInput wj2Input = new WjSixInput(4,
                1, 1, 1, 9, null, null,
                6, 6, 7, 32, null, null,
                260, 235, 435, 525, null, null,
                pr, 82808, bd, 112,3000,300);

        getOut(wj2Input);
    }

    // 8个未知数 未做数据校验，请不要输入负数或大大超过各范围的参数
    public static List<WjSixOutput> getOut(WjSixInput wj2Input) {
        System.out.println("startTime = " + new Date());
//        int speed1 = wj2Input.getSpeed1();
//        int speed2 = wj2Input.getSpeed2();
//        int speed3 = wj2Input.getSpeed3();
//        int speed4 = wj2Input.getSpeed4();
//
//        int floor1 = wj2Input.getFloor1();
//        int floor2 = wj2Input.getFloor2();
//        int floor3 = wj2Input.getFloor3();
//        int floor4 = wj2Input.getFloor4();

        int number = wj2Input.getNumber();

        Integer area1 = wj2Input.getArea1();
        Integer area2 = wj2Input.getArea2();
        Integer area3 = wj2Input.getArea3();
        Integer area4 = wj2Input.getArea4();
        Integer area5 = wj2Input.getArea5();
        Integer area6 = wj2Input.getArea6();

        BigDecimal pr = wj2Input.getPr();
        int la = wj2Input.getLa();
        BigDecimal bd = wj2Input.getBd();
        int plus = wj2Input.getPlus();

        int minX = 0;

        int maxX1 = bd.multiply(new BigDecimal(la)).divide(new BigDecimal(area1), RoundingMode.DOWN).intValue() + 1;
        int maxX2 = bd.multiply(new BigDecimal(la)).divide(new BigDecimal(area2), RoundingMode.DOWN).intValue() + 1;
        ;
        int maxX3 = 0;
        int maxX4 = 0;
        int maxX5 = 0;
        int maxX6 = 0;
        if(area3!=null){
            if(area3 ==0){
                System.out.println("area 参数不能为0 ");
                return null;
            }
            maxX3 = bd.multiply(new BigDecimal(la)).divide(new BigDecimal(area3), RoundingMode.DOWN).intValue() + 1;
        }
        if(area4!=null){
            if(area4 ==0){
                System.out.println("area 参数不能为0 ");
                return null;
            }
            maxX4 = bd.multiply(new BigDecimal(la)).divide(new BigDecimal(area4), RoundingMode.DOWN).intValue() + 1;
        }
        if(area5!=null){
            if(area5 ==0){
                System.out.println("area 参数不能为0 ");
                return null;
            }
            maxX5 = bd.multiply(new BigDecimal(la)).divide(new BigDecimal(area5), RoundingMode.DOWN).intValue() + 1;
        }
        if(area6!=null){
            if(area6 ==0){
                System.out.println("area 参数不能为0 ");
                return null;
            }
            maxX6 = bd.multiply(new BigDecimal(la)).divide(new BigDecimal(area6), RoundingMode.DOWN).intValue() + 1;
        }

        int two = pr.multiply(new BigDecimal(la)).intValue();
        int three = bd.multiply(new BigDecimal(la)).intValue();
        int min2 = wj2Input.getMin2();
        int min3 = wj2Input.getMin3();

        System.out.println(maxX1);
        System.out.println(maxX2);
        System.out.println(maxX3);
        System.out.println(maxX4);
        System.out.println(maxX5);
        System.out.println(maxX6);
        System.out.println(two);
        System.out.println(three);

        List<WjSixOutput> outputList = new ArrayList<>(100);

        switch (number) {
            case 2:
                for (int x1No = minX; x1No <= maxX1; x1No++) {
                    for (int x2No = minX; x2No <= maxX2; x2No++) {
                        WjSixOutput output = new WjSixOutput(x1No, x2No, null, null, null, null);
                        if ((wj2Input.getOne(output) >= plus)
                                && ((wj2Input.getTwo(output) <= two) && (wj2Input.getTwo(output) >= (two - min2)))
                                && ((wj2Input.getThree(output) <= three) && (wj2Input.getThree(output) >= (three - min3))) ){
                            outputList.add(output);
                        }
                    }
                }
                break;
            case 3:
                for (int x1No = minX; x1No <= maxX1; x1No++) {
                    for (int x2No = minX; x2No <= maxX2; x2No++) {
                        for (int x3No = minX; x3No <= maxX3; x3No++) {
                            WjSixOutput output = new WjSixOutput(x1No, x2No, x3No, null, null, null);
                            if ((wj2Input.getOne(output) >= plus)
                                    && ((wj2Input.getTwo(output) <= two) && (wj2Input.getTwo(output) >= (two - min2)))
                                    && ((wj2Input.getThree(output) <= three) && (wj2Input.getThree(output) >= (three - min3))) ){
                                outputList.add(output);
                            }
                        }
                    }
                }
                break;
            case 4:
                for (int x1No = minX; x1No <= maxX1; x1No++) {
                    for (int x2No = minX; x2No <= maxX2; x2No++) {
                        for (int x3No = minX; x3No <= maxX3; x3No++) {
                            for (int x4No = minX; x4No <= maxX4; x4No++) {
                                WjSixOutput output = new WjSixOutput(x1No, x2No, x3No, x4No, null, null);
                                if ((wj2Input.getOne(output) >= plus)
                                        && ((wj2Input.getTwo(output) <= two) && (wj2Input.getTwo(output) >= (two - min2)))
                                        && ((wj2Input.getThree(output) <= three) && (wj2Input.getThree(output) >= (three - min3))) ){
                                    outputList.add(output);
                                }
                            }
                        }
                    }
                }
                break;
            case 5:
                for (int x1No = minX; x1No <= maxX1; x1No++) {
                    for (int x2No = minX; x2No <= maxX2; x2No++) {
                        for (int x3No = minX; x3No <= maxX3; x3No++) {
                            for (int x4No = minX; x4No <= maxX4; x4No++) {
                                for (int x5No = minX; x5No <= maxX5; x5No++) {
                                    WjSixOutput output = new WjSixOutput(x1No, x2No, x3No, x4No, x5No, null);
                                    if ((wj2Input.getOne(output) >= plus)
                                            && ((wj2Input.getTwo(output) <= two) && (wj2Input.getTwo(output) >= (two - min2)))
                                            && ((wj2Input.getThree(output) <= three) && (wj2Input.getThree(output) >= (three - min3))) ){
                                        outputList.add(output);
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            case 6:
                for (int x1No = minX; x1No <= maxX1; x1No++) {
                    for (int x2No = minX; x2No <= maxX2; x2No++) {
                        for (int x3No = minX; x3No <= maxX3; x3No++) {
                            for (int x4No = minX; x4No <= maxX4; x4No++) {
                                for (int x5No = minX; x5No <= maxX5; x5No++) {
                                    for (int x6No = minX; x6No <= maxX6; x6No++) {
                                        WjSixOutput output = new WjSixOutput(x1No, x2No, x3No, x4No, x5No, x6No);
                                        if ((wj2Input.getOne(output) >= plus)
                                                && ((wj2Input.getTwo(output) <= two) && (wj2Input.getTwo(output) >= (two - min2)))
                                                && ((wj2Input.getThree(output) <= three) && (wj2Input.getThree(output) >= (three - min3))) ){
                                            outputList.add(output);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                break;
            default:
                System.out.println("number 只能是2-6的数字");
                return null;
        }
        System.out.println("endTime = " + new Date());
        System.out.println("outputList.size() = " +outputList.size());
//        for(WjSixOutput wjSixOutput : outputList){
//            System.out.println(wjSixOutput.toString());
//        }
        return outputList;
    }

}
